/*
	Stargate SENT for GarrysMod10
	Copyright (C) 2007  aVoN

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

--################# HEADER #################
--################# Include
AddCSLuaFile("cl_init.lua");
AddCSLuaFile("shared.lua");
include("shared.lua");
include("modules/super_dial.lua");
--################# Defines
-- Models
ENT.Models = {
	Base="models/Zup/Super_Gate/super_gate_phys_ring.mdl";
	Parts={
		"models/Zup/Super_Gate/super_gate_bottom_left_nc.mdl",
		"models/Zup/Super_Gate/super_gate_bottom_right_nc.mdl",
		"models/Zup/Super_Gate/super_gate_top_left_nc.mdl",
		"models/Zup/Super_Gate/super_gate_top_right_nc.mdl",
	},
	Dial={
		"models/Zup/Super_Gate/super_gate_energy_ring_part1.mdl",
		"models/Zup/Super_Gate/super_gate_energy_ring_part2.mdl",
	},
	Zappy={
		"models/Zup/Super_Gate/super_gate_zappy.mdl",
	},
}
-- Sounds
ENT.Sounds = {
	Ring=Sound("supergate/supergate_roll.wav"),
    Open=Sound("supergate/supergate_open.wav"),
	Travel=Sound("supergate/supergate_travel.mp3"),
	Close=Sound("supergate/supergate_shutdown.wav"),
	Chevron=Sound("supergate/supergate_chevron_outbound.wav"),
	Inbound=Sound("supergate/supergate_chevron_inbound.wav"),
	Lock=Sound("supergate/supergate_chevron_lock.wav"),
	LockInbound=Sound("supergate/supergate_chevron_lock_inbound.wav"),
	Fail=Sound("supergate/supergate_dial_fail.wav"),
}
-- In which slot do the chevron a lock?
ENT.ChevronLocks = {5,8,11,14,26,29,32,14,20};
ENT.AlwaysFast = true; -- Tells the activation code in stargate_base/events.lua:ActivateStargate() not to add a delay when called by this gate here (Atlantis always dials fast!)
--################# SENT CODE ###############

--################# Init @aVoN
function ENT:Initialize()
	self.Entity:SetModel(self.Models.Base);
	self.Entity:PhysicsInit(SOLID_VPHYSICS);
	self.Entity:SetMoveType(MOVETYPE_VPHYSICS);
	self.Entity:SetSolid(SOLID_VPHYSICS);
	self.BaseClass.Initialize(self); -- BaseClass Initialize call
	self:AddParts();
	self:AddRing();
	self:AddZappy();
end

--################# Either allow the player to spawn this or not
function ENT:SpawnFunction(p,t)
	if (not t.Hit) then return end
	local e = ents.Create("stargate_super");
	e:SetPos(t.HitPos+Vector(0,0,500));
	e:Spawn();
	e:Activate();
	--################# Set correct angle for the spawned prop
	local ang = p:GetAimVector():Angle(); ang.p = 0; ang.r = 0; ang.y = (ang.y+180) % 360
	e:SetAngles(ang);
	return e;
end

--################# Adds all chevrons @aVoN
function ENT:AddParts()
	local pos = self.Entity:GetPos();
	for i=1,4 do
		local e = ents.Create("prop_dynamic_override");
		e:SetModel(self.Models.Parts[i]);
		e:SetParent(self.Entity);
		e:SetDerive(self.Entity); -- Derive Material/Color from "Parent"
		e:DrawShadow(false);
		e:SetPos(pos);
		e:Spawn();
		e:Activate();
	end
end

--################# Creates the ring for the gate @aVoN
function ENT:AddRing()
	local pos = self.Entity:GetPos();
	self.Ring = {Dial={},};
	for i=1,2 do
		local e = ents.Create("prop_dynamic_override");
		e:SetModel(self.Models.Dial[i]);
		e:SetPos(pos);
		e:SetParent(self.Entity);
		e:SetDerive(self.Entity); -- Derive Material/Color from "Parent"
		e:DrawShadow(false);
		e:Spawn();
		e:Activate();
		self.Ring.Dial[i] = e;
	end
end

--################# Creates the ring for the gate @aVoN
function ENT:AddZappy()
	local pos = self.Entity:GetPos();
	local e = ents.Create("func_rotating");
	e:SetKeyValue("spawnflags",4); -- rotate around x-axis
	e:SetKeyValue("rendermode",10); -- dont draw,or the game crashes on touch
	e:SetKeyValue("maxspeed",55);
	e:SetModel(self.Models.Zappy[1]);  -- Dummy model, or the game crashes if you touch the func_rotating
	e:SetParent(self.Entity);
	e:SetPos(pos);
	e:Spawn();
	e:Activate();
	self.Ring.Zappy = e;
	--Spawn the "real" ring (model)
	local e = ents.Create("prop_dynamic_override");
	e:SetModel(self.Models.Zappy[1]);
	e:SetKeyValue("solid",0);
	e:SetPos(pos);
	e:SetParent(self.Ring.Zappy);
	e:SetDerive(self.Entity); -- Derive Material/Color from "Parent"
	e:DrawShadow(false);
	e:Spawn();
	e:Activate();
	self.Ring.Zappy2 = e;				-- RIGHT HERE GAVE ME SO MANY PROBLEMS!!!
	self.Ring.Zappy2:SetNoDraw(true);
end

--################# Turns on a light on the ring @aVoN
function ENT:RingLight(light,inbound)
	local ring = self.Ring.Dial;
	local part = 1;
	if(light < 0) then
		light = light % 36;
	elseif(light > 36) then
		light = light - 36;
	end
	if(light > 16) then
		part = 2; -- Take second  ring part
		light = light - 16;
		-- Deactivate the other ring part. We don't need it anymore
		ring[1]:Fire("SetBodyGroup",0);
	else
		-- Deactivate the other ring part. We don't need it anymore
		ring[2]:Fire("SetBodyGroup",0);
	end
	ring[part]:Fire("SetBodyGroup",light);
end

--################# Makes it rotate or stop @aVoN
function ENT:ActivateRing(b)
	if(not ValidEntity(self.Ring.Zappy)) then return end;
	if(b) then
		self.Ring.Zappy2:SetNoDraw(false);
		--self.Ring:Fire("Reverse","",0); -- Reverse direction first
		self.Ring.Zappy:Fire("start","",0);
		self.Entity:EmitSound(self.Sounds.Ring,90,math.random(97,103));
	else
		self.Ring.Zappy2:SetNoDraw(true);
		self.Ring.Zappy:Fire("stop","",0);
		self.Entity:StopSound(self.Sounds.Ring);
	end
end

--################# Stops the gate's lights
function ENT:Shutdown()
	if(not (self and self.RingLight)) then return end;
	self:RingLight(0,true);
	self:RingLight(0,false);
	self.Entity:Fire("SetBodyGroup",0,0.05); -- Needs a certain delay
end
